using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Windows.Forms;

namespace VideoSniffer
{
    public partial class MainForm : Form
    {
        private System.ComponentModel.BackgroundWorker backgroundWorker1;
        private List<Assembly> assList;

        public MainForm()
        {
            InitializeComponent();
            
            //  Load all plugins
            string plugDirectory    = Application.StartupPath + "\\Plugins\\";
            if (!Directory.Exists(plugDirectory))
            {
                i("Plugins directory is not exist...");
                return;
            }
            
            string [] files = Directory.GetFiles(Application.StartupPath + "\\Plugins\\", "*.dll");
            if (files.Length == 0)
            {
                i("There is no plugin in the Plugins directory...");
                return;
            }

            assList                     = new List<Assembly>();
            foreach (string file in files)
            {
                Assembly ass            = Assembly.LoadFrom(file);
                assList.Add(ass);
            }
            
            //  Initial the background work thread
            this.backgroundWorker1                      = new System.ComponentModel.BackgroundWorker();
            this.backgroundWorker1.DoWork              += new System.ComponentModel.DoWorkEventHandler(backgroundWorker1_DoWork);
            this.backgroundWorker1.RunWorkerCompleted  += new System.ComponentModel.RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        private void buttonGet_Click(object sender, EventArgs e)
        {
            //  Check input
            if (textBoxSourceURL.Text.Length == 0)
            {
                i("URL is empty!");
                return;
            }
            
            string sourceURL        = textBoxSourceURL.Text.Trim();
            
            //  Get the plugin through the input
            Assembly ass            = null;
            foreach (Assembly assembly in assList)
            {
                Type tp             = assembly.GetType(assembly.GetName().Name + ".Worker");
                MethodInfo method   = tp.GetMethod("CheckURL");
                Object o            = System.Activator.CreateInstance(tp);
                
                bool isFit          = (bool)method.Invoke(o, new object[] {sourceURL});
                if (isFit)
                {
                    ass             = assembly;
                    break;
                }
            }
            if (ass == null)
            {
                i("Can not recognize the URL...");
                return;
            }
            
            //  Working...
            buttonGet.Enabled         = false;
            i(string.Format("Plugin: {0}", ass.GetName().Name));
            i("Getting URL......please wait......");
            this.backgroundWorker1.RunWorkerAsync(new InvokeParams(ass, sourceURL));
        }

        void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            InvokeParams param  = (InvokeParams)e.Argument;
            Assembly ass        = param.Ass;
            Type tp             = ass.GetType(ass.GetName().Name + ".Worker");
            MethodInfo method   = tp.GetMethod("GetSource");
            Object o            = System.Activator.CreateInstance(tp);
            
            string urlResult    = (string)method.Invoke(o, new object[] {param.URL});
            
            e.Result            = urlResult;
        }

        void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            string result           = (string)e.Result;
            if (result.Length == 0)
            {
                i("Get failed!");
                return;
            }

            i("Done!");
            textBoxOutputURL.Text   = result;
            textBoxOutputURL.SelectAll();
            textBoxOutputURL.Copy();
            buttonGet.Enabled = true;
        }
        
        private PageContent getPage(string uri)
        {
            WebRequest request      = WebRequest.Create(uri);
            WebResponse response    = request.GetResponse();
            
            string statusCode       = ((HttpWebResponse)response).StatusCode.ToString();
            
            Stream dataStream       = response.GetResponseStream();
            StreamReader reader     = new StreamReader(dataStream);
            string responseFS       = reader.ReadToEnd();
            
            reader.Close();
            response.Close();
            
            return new PageContent(statusCode, responseFS);
        }
        
        private void i(string s)
        {
            textBoxMessage.Text   += DateTime.Now.ToString() + ": " + s + "\r\n";
        }

        private void buttonClear_Click(object sender, EventArgs e)
        {
            textBoxMessage.Text     = string.Empty;
        }
    }
}